﻿namespace UserInterface
{
	using System;
	using System.Collections.Specialized;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Data;
	using System.Drawing;
	using System.Linq;
	using System.Text;
	using System.Windows.Forms;

	using BrainTechLLC;
	using BrainTechLLC.ThreadSafeObjects;

	public partial class Form1 : Form
	{
		#region Fields

		public int _lastSelectedRow = -1;

		#endregion Fields

		#region Constructors

		public Form1()
		{
			InitializeComponent();
		}

		#endregion Constructors

		#region Methods

		public void AppendOutput(string s)
		{
			if (InvokeRequired)
				Invoke(new Action(() => UnsafeAppend(s)));
			else
				UnsafeAppend(s);
		}

		public void RebindGrid()
		{
			List<Type> types = new List<Type>();
			foreach (int n in listBox1.SelectedIndices)
			{
				types.Add(TypeProvider.GetInstance().GetType(listBox1.Items[n].ToString()));
			}
			if (types.Count == 0)
			{
				types.Add(typeof(GameThingBaseClass));
			}
			List<GameThingBaseClass> things = Everything.FindAllThingsOfType<GameThingBaseClass>(types.ToArray());
			gameThingBaseClassBindingSource.DataSource = things;
		}

		void Program_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
		{
			NotifyCollectionChangedEventArgsEx<IdentifierAndValue> args = e as NotifyCollectionChangedEventArgsEx<IdentifierAndValue>;
			if (args.Action == NotifyCollectionChangedAction.Replace)
			{
				AppendOutput(args.OldItems.Grab<IdentifierAndValue>().Value.ToString() + "-->" + args.NewItems.Grab<IdentifierAndValue>().Value.ToString());
			}
		}

		void Program_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			PropertyChangedEventArgsEx args = e as PropertyChangedEventArgsEx;
			AppendOutput(args.PropertyName + "-->" + args.NewValue.ToString());
		}

		void _connectionPoint_NewNotificationPublished(object sender, EventArgs e)
		{
			ConnectionPoint c = sender as ConnectionPoint;
			INotificationMessage o;
			// HEREHERE - do not use the notifications from the connection point - use the ones on the notifier
			// or pass the data through...?
			while (c.Notifications.Dequeue(out o))
			{
				AppendOutput(o.NotificationObject.ToString());
			}
		}

		protected void UnsafeAppend(string s)
		{
			if (outputToTextWindowToolStripMenuItem.Checked)
			{
				txtOutput.AppendText(Environment.NewLine + s);
				txtOutput.SelectionStart = txtOutput.Text.Length;
			}
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			GameSetup.CheckInit();

            GameSetup.chr[0].PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Program_PropertyChanged);
            GameSetup.chr[0].CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Program_CollectionChanged);
            GameSetup._connectionPoint.NewNotificationPublished += new EventHandler(_connectionPoint_NewNotificationPublished);

			RebindGrid();
			txtInput.Focus();
		}

		private void dataGridView1_SelectionChanged(object sender, EventArgs e)
		{
			if (dataGridView1.SelectedCells != null && dataGridView1.SelectedCells.Count > 0)
			{
				int row = dataGridView1.SelectedCells[0].RowIndex;
				if (_lastSelectedRow != row)
				{
					_lastSelectedRow = row;
					object o = dataGridView1.Rows[row].DataBoundItem;
					propertyGridView1.ViewingObject = o;
					baseGameThingEditor1.SetItem(o as GameThingBaseClass);
					gameCharEditor1.SetItem(o as GameChar);
				}
			}
		}

		private void exitToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Application.Exit();
		}

		private void gameStatsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			PropertyGridForm form = new PropertyGridForm();
			form.Show();
			Application.DoEvents();
			form.ViewingObject = GlobalMonitor.GetInstance();
		}

		private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
		{
			RebindGrid();
		}

		private void saveStateToolStripMenuItem_Click(object sender, EventArgs e)
		{
			WorldMap.Instance.Save(null);
		}

		private void tmrUpdate_Tick(object sender, EventArgs e)
		{
			this.Text = Globals.SchedulingEngine.WorkItemsExecuted.ToString();
		}

		private void txtInput_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Enter)
			{
				e.Handled = true;
				e.SuppressKeyPress = true;

				string input = txtInput.Text;
				txtInput.Text = string.Empty;

                CommandToPerform cmd = input.ParseInputText(GameSetup.chr[0]);

				if (cmd != null)
                    GameSetup._connectionPoint.SendCommandToGameThing(cmd);

				// Globals.SchedulingEngine.ScheduleEventToExecute(cmd, 50);

				//List<GameChar> allChars = WorldMap.Instance.FindAllThingsOfType<GameChar>();
				//foreach (GameChar chr in allChars)
				//{
				//   cmd = input.ParseInputText(chr);

				//   if (cmd != null)
				//      Globals.SchedulingEngine.ScheduleEventToExecute(cmd, 50);
				//}
			}
		}

		#endregion Methods

		private void mapToolStripMenuItem_Click(object sender, EventArgs e)
		{
			MapForm map = new MapForm();
			map.mapVisualizer1.World = WorldMap.Instance.World;
			map.Show();
			map.mapVisualizer1.UpdateDisplay();
		}

        private void Form1_Activated(object sender, EventArgs e)
        {
            txtInput.Focus();
            txtInput.SelectAll();
        }
	}
}